<template>
  <div class='p-home'>
    <el-container>
      <el-header>
        <h1>签到奖励器</h1>
      </el-header>
      <el-main>
        <el-row :gutter='12'>
          <!-- 时钟表盘 -->
          <el-col :span='8'>
            <div id='clock'></div>
          </el-col>
          <!-- 签到器 -->
          <el-col :span='8'>
            <section className='signInBox'>
              <time>{{ now }}</time>
              <article :class="'signIn ' + (isLate || hasSignIn ? ' disabled' : '')">
                <button className='btn' @click='signIn'>签 到</button>
              </article>
              <div class='signTipText'>
                <template v-if='hasSignIn'>
                  {{ 高兴的字符表情 }}<br />今天已经签到了，明天再来吧
                </template>
                <template v-else-if='isLate'>
                  {{ 不高兴的字符表情 }}<br />今天已经晚了，明天再来吧
                </template>
                <template v-else>
                  ^_^<br />快点来呀
                </template>
              </div>
              <div class='deadline'>今日签到时间截止：{{ clock }}</div>
              <div class='score'>
                <strong>{{ totalScore }}</strong>分 / <strong>{{ data.length }}</strong>天
                <div class='desc'>{{ totalScore }}={{ leftOver }}(之前剩余)+{{ signInScore }}(签到)+{{ targetsScore
                  }}(小目标)
                </div>
              </div>
            </section>
          </el-col>
          <el-col :span='8'>
            <div id='historyLine' ref='historyLine'></div>
          </el-col>
        </el-row>
        <el-row :gutter='12'>
          <el-col :span='24'>
            <Awards :totalScore='totalScore' />
          </el-col>
        </el-row>
        <el-row :gutter='12'>
          <el-col :span='24'>
            <Score />
          </el-col>
        </el-row>
        <el-row :gutter='12'>
          <el-col :span='24'>
            <Links />
          </el-col>
        </el-row>
      </el-main>
    </el-container>
  </div>

</template>

<script lang='ts' setup>

import { onMounted, ref, watch, reactive, computed } from "vue"
import "./jquery.thooClock.js";
import dayjs, { Dayjs } from 'dayjs'
import * as echarts from 'echarts/core'
import { LineChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers';
import { GridComponent, TooltipComponent, MarkLineComponent, DataZoomComponent } from 'echarts/components'
import Awards from './components/awards.vue'
import Score from './components/score.vue'
import { targets } from './utils/config.js'
import './assets/common.scss'
import Links from './components/links.vue';

const test = 0
echarts.use([CanvasRenderer, LineChart, GridComponent, TooltipComponent, MarkLineComponent, DataZoomComponent])
const now = ref()
const isLate = ref(false)

// 平时7:25，周六日8:00
let clock = '7:25:00'
let day = new Date().getDay()
if (day === 0 || day === 6) {
  clock = '8:00:00'
}
clock = '07:40:00' 
let hasSignIn = ref(true)
const 高兴的字符表情 = rdm(['O(∩_∩)O', '╰(*°▽°*)╯', '(*￣3￣)╭', ' o(￣▽￣)ｄ', '♪(^∇^*)', 'ㄟ(≧◇≦)ㄏ', ' (＾－＾)V', ' ︿(￣︶￣)︿', '(((o(*ﾟ▽ﾟ*)o)))', 'o(*￣▽￣*)o'])
const 不高兴的字符表情 = rdm(['┭┮﹏┭┮', '～>_<～', 'o(╥﹏╥) ', ' (；′⌒`)', ' X﹏X', '（┬_┬）', '（>﹏<）', '（（‵□′））', '<(￣3￣)>', ' (￣△￣；)'])

const data = ref(JSON.parse(localStorage.getItem('signInDatas') || '[]'))
const leftOver = 455
const targetsScore = targets.filter(item => item.done).reduce((pre, next) => pre + next.score, 0)
const signInScore = computed(() => data.value.length * 5)
const totalScore = computed(() => signInScore.value + targetsScore + leftOver)
let chart = {}
const chartOpt = {
  dataZoom: [
    {
      type: 'inside',
      realtime: true,
      start: 30,
      end: 70,
      xAxisIndex: [0, 1]
    }
  ],
  grid: {
    left: '20%'
  },
  tooltip: {
    trigger: 'axis',
    valueFormatter: v => sec2hhmmss(v)
  },
  xAxis: {
    axisLabel: {
      rotate: 45
    },
    data: data.value.map(item => item.date.slice(-5).replaceAll('0', ''))
  },
  yAxis: {
    type: 'value',
    axisLabel: {
      formatter: v => sec2hhmmss(v)
    },
    min: 6.5 * 3600,
    max: 8 * 3600,
  },
  series: [
    {
      data: data.value.map(item => getSeconds(item.time)),
      type: 'line',
      markLine: {
        data: [
          {
            symbol: 'none',
            yAxis: 7 * 3600 + 25 * 60,
            label: {
              position: 'start',
              formatter: sec2hhmmss(7 * 3600 + 25 * 60)
            },
          }
        ]
      },
    }
  ]
}
const historyLine = ref(null)

onMounted(() => {
  $('#clock').thooClock({
    size: 360,
    sweepingSeconds: false,
    showNumerals: true,
    numeralFont: 'Times New Roman',
    numerals: [
      { 1: 'I' },
      { 2: 'II' },
      { 3: 'III' },
      { 4: 'IV' },
      { 5: 'V' },
      { 6: 'VI' },
      { 7: 'VII' },
      { 8: 'VIII' },
      { 9: 'IX' },
      { 10: 'X' },
      { 11: 'XI' },
      { 12: 'XII' }
    ]
  })
  chart = echarts.init(historyLine.value)
  chart.setOption(chartOpt)

  const init = () => {

    const _now = new Date()
    now.value = dayjs(_now).format('HH:mm:ss')
    // 是否过点
    const h = _now.getHours()
    const m = _now.getMinutes()
    const s = _now.getSeconds()
    const arr = clock.split(':')
    if (h * 3600 + m * 60 + s >= arr[0] * 3600 + arr[1] * 60 + (arr[2] - 0)) {
      isLate.value = true
    }
    test && (isLate.value = false)
  }
  init()
  setInterval(init, 500)
  // 今天是否已签到
  const _data = JSON.parse(localStorage.getItem('signInDatas') || '[]')
  const lastDate = _data?.length && _data.at(-1).date.split('-')
  if (lastDate) {
    const _now = new Date()
    const year = (_now.getFullYear() + '').slice(2)
    const month = (_now.getMonth() + 1 + '').padStart(2, '0')
    const date = (_now.getDate() + '').padStart(2, '0')
    hasSignIn.value = lastDate && year === lastDate[0] && month === lastDate[1] && date === lastDate[2]
  } else {
    // 第一次签到
    hasSignIn.value = false
  }
  // 测试连续签到
  test && (hasSignIn.value = false)
})
const addScore = () => {
  document.querySelector('.signIn .btn').classList.add('add5')
}
const saveAs = (data: Object, t: Dayjs) => {
  const fileData = JSON.stringify(data, null, 4)
  var a = document.createElement('a')
  a.href = 'data:application/json;charset=utf-8,' + encodeURIComponent(fileData)
  a.download = `签到数据_${t.format('YY-MM-DD hh:mm')}`
  a.click()
}
const upDateChart = () => {
  const _data = JSON.parse(localStorage.getItem('signInDatas') || '[]')
  chartOpt.xAxis.data = _data.map(item => item.date.slice(-5).replaceAll('0', ''))
  chartOpt.series[0].data = _data.map(item => getSeconds(item.time))
  chart.setOption(chartOpt)
}
// 签到动作
const signIn = () => {
  const t = dayjs(new Date())
  const _data = [...data.value,
  {
    date: t.format('YY-MM-DD'),
    time: t.format('HH:mm:ss')
  }]
  hasSignIn.value = true
  localStorage.setItem('signInDatas', JSON.stringify(_data))
  addScore()
  saveAs(_data, t)
  upDateChart()
}
watch(hasSignIn, () => {
  // 测试连续签到
  test && (hasSignIn.value = false)
  setTimeout(() => {
    data.value = JSON.parse(localStorage.getItem('signInDatas') || '[]')
  }, 100)
})
function rdm(arr) {
  const ret = arr[Math.floor(arr.length * Math.random())]
  return ret
}
function getSeconds(str) {
  const [h, m, s] = str.split(':')
  return h * 3600 + m * 60 + Number(s)
}
function sec2hhmmss(v) {
  // 将数值格式化为时间，例如HH:mm:ss
  // console.log('~~v', v)
  var h = Math.floor(v / 3600);
  var m = Math.floor(((v - h * 3600) / 60));
  var s = Math.round((v % 60));
  return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
}
</script>

<style scoped>
h1 {
  text-align: center;
}

.el-main {
  overflow: initial;

  &>.el-row {
    margin-bottom: 12px;
  }

}

.el-col>* {
  height: 100%;
  border-radius: 8px;
  background-color: var(--bg-200);
}

/* 时钟 */
#clock {
  height: 400px;
  padding-block: 20px;
  display: flex;
  justify-content: center;
}

@keyframes scale {

  from,
  to {
    scale: 1;
  }

  40% {
    scale: 1.2;
  }
}

@keyframes add5 {

  from {
    scale: 1;
    top: 0;
    opacity: 1;
  }

  to {
    top: -15rem;
    opacity: 0;
    scale: 1.5;
  }
}

/* 签到 */
.signInBox {
  text-align: center;

  time {
    font-size: 3rem;
    font-weight: bold;
    line-height: 9rem;
  }

  .signIn {
    .btn {
      position: relative;
      margin-bottom: 1rem;
      font-size: 2rem;
      width: 10rem;
      line-height: 3rem;
      border-radius: 1.5rem;
      border: none;
      box-shadow: .125rem .125rem .5rem var(--primary-300);
      background-color: var(--primary-100);
      cursor: pointer;
      transition: all .36s;

      &:hover {
        background-color: var(--primary-200);
      }

      &:active {
        left: .125rem;
        top: .125rem;
        transition: none;
        background-color: var(--primary-300);
        box-shadow: 0 0 .25rem var(--primary-300);
      }

      /* +5动画 */
      &::before {
        content: '+5';
        position: absolute;
        left: 50%;
        top: 0;
        translate: -50%;
        font-size: 3rem;
        opacity: 0;
        color: var(--primary-200);
        text-shadow: 0 0 .5rem var(--accent-100);
      }

      &.add5 {
        &:before {
          animation: add5 1s linear;
        }
      }
    }

    &.disabled {
      button {
        pointer-events: none;
        opacity: .5;
        animation: none;
      }

    }
  }

  .signTipText {
    font-size: 1.25rem;
    line-height: 3rem;
  }

  .score {
    line-height: 2rem;
    font-size: 20px;

    strong {
      font-size: 32px;
      color: var(--primary-200);
    }
  }

  .deadline,
  .desc {
    color: var(--text-200);
    font-size: 16px;
  }

  .deadline {
    margin-bottom: 1.5rem;
  }
}
</style>
